﻿using System;
using System.Collections.Generic;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Cms.Utilities;
using Cms.Web.Framework.Controls;
using Cms.Web.UI.Admin.HelperClasses;
using iLib.Web.UI;
using MenuItem = Cms.Domain.MenuItem;
using Page = Cms.Domain.Page;

namespace Cms.Web.UI.Admin
{
    public partial class EditMenuItem : AdminPage, IEditMenuItemView
    {
        private EditMenuItemPresenter _presenter;

        #region IEditMenuItemView Members

        public int MenuItemID
        {
            get { return QueryString.GetInt32ID("id"); }
        }


        public int MenuID
        {
            get { return QueryString.GetInt32ID("menuid"); }
        }


        public int VersionID
        {
            get { return QueryString.GetInt32ID("versionid"); }
        }


        public int LocaleID
        {
            get { return QueryString.GetInt32ID("localeid"); }
        }


        public string ContextTranslationFile
        {
            get { return "Admin/Translations/EditMenuItem.xml"; }
        }


        public void SetLocales(IList<Locale> locales)
        {
            ddlLocales.Items.Clear();
            foreach (Locale l in locales)
                ddlLocales.Items.Add(new ListItem(l.GetTranslation(Localization).Name, l.ID.ToString()));
        }


        public int SelectedLocaleID
        {
            get { return int.Parse(ddlLocales.SelectedValue); }
            set { ddlLocales.SelectedValue = value.ToString(); }
        }


        public void SetParentMenuItems(string menuName, IList<MenuItem> items)
        {
            ddlParentMenuItems.Items.Add(new ListItem(menuName, "-1"));
            SetParentMenuItemTree(1, items);
        }


        public int SelectedParentMenuItemID
        {
            get { return int.Parse(ddlParentMenuItems.SelectedValue); }
            set { ddlParentMenuItems.SelectedValue = value.ToString(); }
        }


        public string Name
        {
            get { return txtName.Text; }
            set { txtName.Text = value; }
        }


        public void SetDefaultImage(MediaFile file)
        {
            SetImage(file, imgDefaultImage, lbDeleteDefaultImage, litDeleteDefaultImagePipe, litDefaultImage,
                     hidDefaultImageID, "NoDefaultImage");
        }


        public void SetActiveImage(MediaFile file)
        {
            SetImage(file, imgActiveImage, lbDeleteActiveImage, litDeleteActiveImagePipe, litActiveImage,
                     hidActiveImageID, "NoActiveImage");
        }


        public void SetDefaultHoverImage(MediaFile file)
        {
            SetImage(file, imgDefaultHoverImage, lbDeleteDefaultHoverImage, litDeleteDefaultHoverImagePipe,
                     litDefaultHoverImage, hidDefaultHoverImageID, "NoDefaultHoverImage");
        }


        public void SetActiveHoverImage(MediaFile file)
        {
            SetImage(file, imgActiveHoverImage, lbDeleteActiveHoverImage, litDeleteActiveHoverImagePipe,
                     litActiveHoverImage, hidActiveHoverImageID, "NoActiveHoverImage");
        }


        public int SelectedDefaultImageID
        {
            get { return int.Parse(hidDefaultImageID.Value); }
        }


        public int SelectedActiveImageID
        {
            get { return int.Parse(hidActiveImageID.Value); }
        }


        public int SelectedDefaultHoverImageID
        {
            get { return int.Parse(hidDefaultHoverImageID.Value); }
        }


        public int SelectedActiveHoverImageID
        {
            get { return int.Parse(hidActiveHoverImageID.Value); }
        }


        public MenuItemLinkType LinkTypes
        {
            get
            {
                if (rbPage.Checked)
                    return MenuItemLinkType.Page;
                if (rbUrl.Checked)
                    return MenuItemLinkType.Url;
                return MenuItemLinkType.Nothing;
            }
            set
            {
                rbPage.Checked = false;
                rbUrl.Checked = false;
                rbNothing.Checked = false;
                trPage.Visible = false;
                trUrl.Visible = false;
                switch (value)
                {
                    case MenuItemLinkType.Page:
                        rbPage.Checked = true;
                        trPage.Visible = true;
                        break;
                    case MenuItemLinkType.Url:
                        rbUrl.Checked = true;
                        trUrl.Visible = true;
                        break;
                    case MenuItemLinkType.Nothing:
                        rbNothing.Checked = true;
                        break;
                }
            }
        }


        public void SetFolders(string domain, IList<Folder> folders)
        {
            ddlFolders.Items.Clear();
            ddlFolders.Items.Add(new ListItem(domain, "-1"));
            SetFolderTree(1, folders);
        }


        public int SelectedFolderID
        {
            get { return int.Parse(ddlFolders.SelectedValue); }
            set { ddlFolders.SelectedValue = value.ToString(); }
        }


        public void SetPages(IList<Page> pages)
        {
            ddlPages.Items.Clear();
            foreach (Page p in pages)
            {
                ddlPages.Items.Add(new ListItem(p.Name, p.ID.ToString()));
            }
            ddlPages.Visible = pages.Count > 0;
            lblNoPages.Visible = pages.Count == 0;
        }


        public int SelectedPageID
        {
            get
            {
                if (lblNoPages.Visible)
                    return -1;
                return int.Parse(ddlPages.SelectedValue);
            }
            set { ddlPages.SelectedValue = value.ToString(); }
        }


        public string Url
        {
            get { return txtUrl.Text; }
            set { txtUrl.Text = value; }
        }


        public string Target
        {
            get { return ddlTargets.SelectedValue; }
            set { ddlTargets.SelectedValue = value; }
        }


        public void SetCategories(IList<Category> rootCategories)
        {
            ddlCategories.Items.Clear();
            ddlCategories.Items.Add(new ListItem(GetText(this, "ActiveForCategoryDefault"), "-1"));
            CategoriesDropDownHelper.SetCategoryTree(ref ddlCategories, 0, rootCategories);
        }


        public int SelectedCategoryID
        {
            get { return int.Parse(ddlCategories.SelectedValue); }
            set { ddlCategories.SelectedValue = value.ToString(); }
        }

        #endregion

        protected override void OnLoad(EventArgs e)
        {
            if (MenuID == -1 && VersionID == -1)
            {
                Response.Redirect("Menus.aspx");
                return;
            }
            base.OnLoad(e);
            _presenter = new EditMenuItemPresenter(this);
            int selectedLocaleIndex = ddlLocales.SelectedIndex;
            _presenter.SetLocales();
            ddlLocales.SelectedIndex = selectedLocaleIndex;
            if (!Page.IsPostBack)
            {
                ddlTargets.Items.Add(new ListItem(GetText(this, "llSelf"), "self"));
                ddlTargets.Items.Add(new ListItem(GetText(this, "llBlank"), "blank"));
                _presenter.Initialize();
                if (!string.IsNullOrEmpty(Request.QueryString["state"]))
                    DecodeState();
                if (!string.IsNullOrEmpty(Request.QueryString["mediafileid"]))
                    _presenter.UpdateImage(Request.QueryString["target"], int.Parse(Request.QueryString["mediafileid"]));
                HeadingIcon = litIcon.Text;
                hlCancel.NavigateUrl = "Admin/EditMenu.aspx?id=" + MenuID + "&tab=items&versionid=" + VersionID;
            }
            HeadingText = GetText(this, MenuItemID > 0 ? "EditHeading" : "NewHeading");
            txtName.Focus();
        }


        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            trTarget.Visible = !rbNothing.Checked;
        }


        protected void lbSave_Click(object sender, EventArgs e)
        {
            _presenter.Save();
            if (_presenter.IsValid)
                Response.Redirect("EditMenu.aspx?id=" + MenuID + "&tab=items&versionid=" + VersionID);
        }


        protected void lbSelectImage_Click(object sender, EventArgs e)
        {
            // Remove the target parameter from the url if it already exists. That can happen if we browse and click cancel several times.
            string url = Request.Url.AbsoluteUri;
            url = Misc.RemoveParameterFromQueryString(url, "target");
            url = Misc.RemoveParameterFromQueryString(url, "mediafileid");
            url = Misc.RemoveParameterFromQueryString(url, "state");
            string data = "referrer=" + Server.UrlEncode(url) +
                          "&target=" + ((LinkButton) sender).CommandArgument +
                          "&filter=" + Server.UrlEncode("png,gif,jpg") +
                          "&state=" + EncodeState();
            Response.Redirect("Media.aspx?browseitemdata=" + Server.UrlEncode(data));
        }


        private string EncodeState()
        {
            string state = "txtName=" + Server.UrlEncode(txtName.Text) +
                           "&ddlLocales=" + ddlLocales.SelectedValue +
                           "&hidDefaultImageID=" + hidDefaultImageID.Value +
                           "&hidActiveImageID=" + hidActiveImageID.Value +
                           "&hidDefaultHoverImageID=" + hidDefaultHoverImageID.Value +
                           "&hidActiveHoverImageID=" + hidActiveHoverImageID.Value +
                           "&ddlParentMenuItems=" + ddlParentMenuItems.SelectedValue +
                           "&LinkType=";
            if (rbPage.Checked)
                state += "page";
            else if (rbUrl.Checked)
                state += "url";
            else
                state += "nothing";
            state += "&ddlFolders=" + ddlFolders.SelectedValue +
                     "&ddlPages=" + ddlPages.SelectedValue +
                     "&txtUrl=" + txtUrl.Text +
                     "&ddlTargets=" + ddlTargets.SelectedValue;
            return Server.UrlEncode(state);
        }


        private void DecodeState()
        {
            string state = Request.QueryString["state"];
            txtName.Text = Misc.GetBrowseItemDataValue(state, "txtName");
            ddlLocales.SelectedValue = Misc.GetBrowseItemDataValue(state, "ddlLocales");
            _presenter.UpdateImage("defaultimage", int.Parse(Misc.GetBrowseItemDataValue(state, "hidDefaultImageID")));
            _presenter.UpdateImage("activeimage", int.Parse(Misc.GetBrowseItemDataValue(state, "hidActiveImageID")));
            _presenter.UpdateImage("defaulthoverimage",
                                    int.Parse(Misc.GetBrowseItemDataValue(state, "hidDefaultHoverImageID")));
            _presenter.UpdateImage("activehoverimage",
                                    int.Parse(Misc.GetBrowseItemDataValue(state, "hidActiveHoverImageID")));
            ddlParentMenuItems.SelectedValue = Misc.GetBrowseItemDataValue(state, "ddlParentMenuItems");
            rbPage.Checked = false;
            rbUrl.Checked = false;
            rbNothing.Checked = false;
            switch (Misc.GetBrowseItemDataValue(state, "LinkType"))
            {
                case "page":
                    rbPage.Checked = true;
                    break;
                case "url":
                    rbUrl.Checked = true;
                    break;
                case "nothing":
                    rbNothing.Checked = true;
                    break;
            }
            LinkTypes = LinkTypes;
            ddlFolders.SelectedValue = Misc.GetBrowseItemDataValue(state, "ddlFolders");
            _presenter.UpdatePages();
            ddlPages.SelectedValue = Misc.GetBrowseItemDataValue(state, "ddlPages");
            txtUrl.Text = Misc.GetBrowseItemDataValue(state, "txtUrl");
            ddlTargets.SelectedValue = Misc.GetBrowseItemDataValue(state, "ddlTargets");
        }


        protected void lbDeleteImage_Click(object sender, EventArgs e)
        {
            _presenter.UpdateImage(((LinkButton) sender).CommandArgument, -1);
        }


        protected void rbLinkType_Changed(object sender, EventArgs e)
        {
            LinkTypes = LinkTypes; // Use property getter and setter to set GUI
        }


        protected void ddlFolders_Changed(object sender, EventArgs e)
        {
            _presenter.UpdatePages();
        }

        private void SetParentMenuItemTree(int level, IEnumerable<MenuItem> items)
        {
            foreach (MenuItem mi in items)
            {
                string name = mi.GetTranslation(SelectedLocaleID).Name;
                for (int i = 0; i < level; i++)
                    name = "&nbsp;&nbsp;&nbsp;&nbsp;" + name;
                ddlParentMenuItems.Items.Add(new ListItem(name, mi.ID.ToString()));
                SetParentMenuItemTree(level + 1, mi.SubItems);
            }
        }

        private void SetImage(MediaFile file, Image img, LinkButton lbDelete, Literal litDeletePipe, Literal litImage,
                              HtmlInputControl hid, string translationKey)
        {
            if (file == null)
            {
                litImage.Text = GetText(this, translationKey);
                hid.Value = "-1";
            }
            else
            {
                litImage.Text = file.GetVirtualPath();
                img.ImageUrl = iLib.Web.UI.Url.VirtualPath + file.GetVirtualPath();
                hid.Value = file.ID.ToString();
            }
            img.Visible = file != null;
            lbDelete.Visible = img.Visible;
            litDeletePipe.Visible = lbDelete.Visible;
        }

        private void SetFolderTree(int level, IList<Folder> folders)
        {
            foreach (Folder f in folders)
            {
                string name = f.Name;
                for (int i = 0; i < level; i++)
                    name = "&nbsp;&nbsp;&nbsp;&nbsp;" + name;
                ddlFolders.Items.Add(new ListItem(name, f.ID.ToString()));
                SetFolderTree(level + 1, f.SubFolders);
            }
        }
    }
}